import requests
import json
import time
import logging
from typing import List, Dict, Optional
import threading

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class THSAPIClient:
    """同花顺API客户端封装"""

    def __init__(self, base_url: str = "http://127.0.0.1:6003", strategy_no: str = "1001", timeout: int = 10):
        """
        初始化同花顺API客户端

        Args:
            base_url: 同花顺API基础地址
            strategy_no: 策略编号
            timeout: 请求超时时间
        """
        self.base_url = base_url.rstrip('/')
        self.strategy_no = strategy_no
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update({
            'Content-Type': 'application/json',
            'User-Agent': 'THS-Trade-Client/1.0'
        })

        # 测试连接
        self.test_connection()

    def test_connection(self) -> bool:
        """测试与同花顺API的连接"""
        try:
            response = self.session.get(f"{self.base_url}/", timeout=self.timeout)
            if response.status_code == 200:
                logger.info("同花顺API连接成功")
                return True
            else:
                logger.warning(f"同花顺API连接异常，状态码: {response.status_code}")
                return False
        except requests.exceptions.ConnectionError:
            logger.error("无法连接到同花顺API，请确保同花顺软件已启动并开启API服务")
            return False
        except Exception as e:
            logger.error(f"测试连接时发生错误: {e}")
            return False

    def convert_security_code(self, jq_code: str) -> str:
        """
        将聚宽代码转换为同花顺代码格式

        Args:
            jq_code: 聚宽格式的证券代码，如 '000001.XSHE'

        Returns:
            str: 同花顺格式的证券代码，如 '000001.SZ'
        """
        if jq_code.endswith('.XSHG'):
            return jq_code.replace('.XSHG', '.SH')
        elif jq_code.endswith('.XSHE'):
            return jq_code.replace('.XSHE', '.SZ')
        else:
            # 如果不是聚宽格式，直接返回
            return jq_code

    def buy(self, code: str, name: str, amount: int) -> Dict:
        """
        买入操作

        Args:
            code: 证券代码
            name: 证券名称
            amount: 买入数量

        Returns:
            Dict: 操作结果
        """
        return self._place_order(code, name, amount, "buy")

    def sell(self, code: str, name: str, amount: int) -> Dict:
        """
        卖出操作

        Args:
            code: 证券代码
            name: 证券名称
            amount: 卖出数量

        Returns:
            Dict: 操作结果
        """
        return self._place_order(code, name, amount, "sell")

    def _place_order(self, code: str, name: str, amount: int, operate: str) -> Dict:
        """
        下单基础方法

        Args:
            code: 证券代码
            name: 证券名称
            amount: 数量
            operate: 操作类型 'buy' 或 'sell'

        Returns:
            Dict: 操作结果
        """
        try:
            # 转换代码格式
            ths_code = self.convert_security_code(code)

            # 构建订单数据
            order_data = [{
                "strategy_no": self.strategy_no,
                "code": ths_code,
                "name": name,
                "ct_amount": amount,
                "operate": operate
            }]

            logger.info(f"发送{operate}订单: {ths_code}({name}), 数量: {amount}")

            # 发送请求
            response = self.session.post(
                f"{self.base_url}/api/queue",
                json=order_data,
                timeout=self.timeout
            )

            # 解析响应
            if response.status_code == 200:
                result = response.json()
                logger.info(f"下单成功: {result}")
                return {
                    "success": True,
                    "data": result,
                    "message": f"{operate}订单提交成功"
                }
            else:
                error_msg = f"下单失败，状态码: {response.status_code}, 响应: {response.text}"
                logger.error(error_msg)
                return {
                    "success": False,
                    "error": error_msg,
                    "status_code": response.status_code
                }

        except requests.exceptions.Timeout:
            error_msg = "下单请求超时"
            logger.error(error_msg)
            return {"success": False, "error": error_msg}
        except requests.exceptions.ConnectionError:
            error_msg = "无法连接到同花顺API"
            logger.error(error_msg)
            return {"success": False, "error": error_msg}
        except Exception as e:
            error_msg = f"下单时发生未知错误: {e}"
            logger.error(error_msg)
            return {"success": False, "error": error_msg}

    def batch_orders(self, orders: List[Dict]) -> Dict:
        """
        批量下单

        Args:
            orders: 订单列表，每个订单包含 code, name, amount, operate

        Returns:
            Dict: 批量操作结果
        """
        try:
            # 构建批量订单数据
            order_data = []
            for order in orders:
                ths_code = self.convert_security_code(order['code'])
                order_data.append({
                    "strategy_no": self.strategy_no,
                    "code": ths_code,
                    "name": order['name'],
                    "ct_amount": order['amount'],
                    "operate": order['operate']
                })

            logger.info(f"发送批量订单，共 {len(order_data)} 个订单")

            # 发送请求
            response = self.session.post(
                f"{self.base_url}/api/queue",
                json=order_data,
                timeout=self.timeout
            )

            # 解析响应
            if response.status_code == 200:
                result = response.json()
                logger.info(f"批量下单成功: {result}")
                return {
                    "success": True,
                    "data": result,
                    "message": f"批量订单提交成功，共 {len(order_data)} 个订单"
                }
            else:
                error_msg = f"批量下单失败，状态码: {response.status_code}, 响应: {response.text}"
                logger.error(error_msg)
                return {
                    "success": False,
                    "error": error_msg,
                    "status_code": response.status_code
                }

        except Exception as e:
            error_msg = f"批量下单时发生错误: {e}"
            logger.error(error_msg)
            return {"success": False, "error": error_msg}

    def query(self, operate: str) -> Dict:
        """
        查询操作

        Args:
            operate: 查询类型
                    'get_position' - 获取持仓
                    'get_today_trades' - 获取当日成交
                    'get_today_entrusts' - 获取当日委托
                    'get_balance' - 获取资金情况

        Returns:
            Dict: 查询结果
        """
        try:
            query_data = {
                "strategy_no": self.strategy_no,
                "operate": operate
            }

            logger.info(f"执行查询: {operate}")

            # 发送请求
            response = self.session.post(
                f"{self.base_url}/api/search",
                json=query_data,
                timeout=self.timeout
            )

            # 解析响应
            if response.status_code == 200:
                result = response.json()
                logger.info(f"查询成功: {operate}")
                return {
                    "success": True,
                    "data": result,
                    "message": f"{operate}查询成功"
                }
            else:
                error_msg = f"查询失败，状态码: {response.status_code}, 响应: {response.text}"
                logger.error(error_msg)
                return {
                    "success": False,
                    "error": error_msg,
                    "status_code": response.status_code
                }

        except Exception as e:
            error_msg = f"查询时发生错误: {e}"
            logger.error(error_msg)
            return {"success": False, "error": error_msg}

    def get_position(self) -> Dict:
        """获取持仓"""
        return self.query("get_position")

    def get_today_trades(self) -> Dict:
        """获取当日成交"""
        return self.query("get_today_trades")

    def get_today_entrusts(self) -> Dict:
        """获取当日委托（推荐使用）"""
        return self.query("get_today_entrusts")

    def get_balance(self) -> Dict:
        """获取资金情况"""
        return self.query("get_balance")

    def get_account_info(self) -> Dict:
        """获取完整的账户信息"""
        try:
            balance_result = self.get_balance()
            position_result = self.get_position()
            entrusts_result = self.get_today_entrusts()

            return {
                "success": True,
                "balance": balance_result,
                "positions": position_result,
                "entrusts": entrusts_result
            }
        except Exception as e:
            error_msg = f"获取账户信息时发生错误: {e}"
            logger.error(error_msg)
            return {"success": False, "error": error_msg}


class THSTradeManager:
    """同花顺交易管理器"""

    def __init__(self, strategy_no: str = "1001"):
        """
        初始化交易管理器

        Args:
            strategy_no: 策略编号
        """
        self.strategy_no = strategy_no
        self.api_client = THSAPIClient(strategy_no=strategy_no)
        self.order_history = []
        self.max_history_size = 1000

    def process_order_from_redis(self, order_data: Dict) -> Dict:
        """
        处理从Redis接收的订单数据

        Args:
            order_data: 订单数据，包含 security, security_name, amount, is_buy 等字段

        Returns:
            Dict: 处理结果
        """
        try:
            security = order_data.get('security', '')
            security_name = order_data.get('security_name', '')
            amount = order_data.get('amount', 0)
            is_buy = order_data.get('is_buy', True)

            if not security:
                return {"success": False, "error": "缺少证券代码"}

            if amount == 0:
                return {"success": False, "error": "订单数量为0"}

            # 执行下单
            if is_buy:
                result = self.api_client.buy(security, security_name, abs(amount))
            else:
                result = self.api_client.sell(security, security_name, abs(amount))

            # 记录订单历史
            order_record = {
                "timestamp": time.time(),
                "order_data": order_data,
                "result": result
            }
            self.order_history.append(order_record)

            # 限制历史记录大小
            if len(self.order_history) > self.max_history_size:
                self.order_history = self.order_history[-self.max_history_size:]

            return result

        except Exception as e:
            error_msg = f"处理Redis订单时发生错误: {e}"
            logger.error(error_msg)
            return {"success": False, "error": error_msg}

    def get_order_history(self, limit: int = 50) -> List[Dict]:
        """
        获取订单历史

        Args:
            limit: 返回的历史记录条数

        Returns:
            List[Dict]: 订单历史记录
        """
        return self.order_history[-limit:] if self.order_history else []

    def get_trading_status(self) -> Dict:
        """
        获取交易状态信息

        Returns:
            Dict: 交易状态信息
        """
        try:
            account_info = self.api_client.get_account_info()
            return {
                "success": True,
                "strategy_no": self.strategy_no,
                "api_connected": self.api_client.test_connection(),
                "recent_orders": len(self.order_history),
                "account_info": account_info
            }
        except Exception as e:
            return {
                "success": False,
                "error": f"获取交易状态失败: {e}",
                "api_connected": False
            }


# 全局交易管理器实例
_global_trade_manager = None


def get_trade_manager(strategy_no: str = "1001") -> THSTradeManager:
    """
    获取全局交易管理器实例

    Args:
        strategy_no: 策略编号

    Returns:
        THSTradeManager: 交易管理器实例
    """
    global _global_trade_manager
    if _global_trade_manager is None:
        _global_trade_manager = THSTradeManager(strategy_no=strategy_no)
    return _global_trade_manager